home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / session.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-20  |  8.6 KB  |  428 lines

  1. /* Session control */
  2. #include <stdio.h>
  3. #include "global.h"
  4. #include "config.h"
  5. #include "mbuf.h"
  6. #include "proc.h"
  7. #include "ftpcli.h"
  8. #include "icmp.h"
  9. #include "telnet.h"
  10. #include "tty.h"
  11. #include "rlogin.h"
  12. #include "session.h"
  13. #include "hardware.h"
  14. #include "socket.h"
  15. #include "cmdparse.h"
  16. #include "commands.h"
  17. #include "files.h"
  18.  
  19. struct session *Sessions, *Current, *Lastcurr;
  20. extern struct proc *Display;
  21.  
  22. char Notval[] = "Not a valid control block\n";
  23. char Nosess[] = "Too many sessions\n";
  24. static char Badsess[] = "Invalid session\n";
  25.  
  26. char *Sestypes[] = {
  27.     "",
  28.     "Telnet",
  29.     "FTP",
  30.     "AX25",
  31.     "Finger",
  32.     "Ping",
  33.     "NET/ROM",
  34.     "Command",
  35.     "More",
  36.     "Hopcheck",
  37.     "Tip",
  38.     "PPP PAP",
  39.     "Trace",
  40.         "RawIF",
  41.         "Rlogin"
  42. };
  43.  
  44. /* Convert a character string containing a decimal session index number
  45.  * into a pointer. If the arg is NULLCHAR, use the current default session.
  46.  * If the index is out of range or unused, return NULLSESSION.
  47.  */
  48. struct session *
  49. sessptr(cp)
  50. char *cp;
  51. {
  52.     unsigned int i;
  53.  
  54.     struct session *sp = (cp == NULLCHAR)
  55.       ? Lastcurr : ((i = (unsigned)atoi(cp)) >= Nsessions)
  56.         ? NULLSESSION : &Sessions[i+1];
  57.  
  58.     if(sp == NULLSESSION || sp->type == FREE)
  59.         sp = NULLSESSION;
  60.  
  61.     return sp;
  62. }
  63.  
  64. /* Select and display sessions */
  65. int
  66. dosession(argc,argv,p)
  67. int argc;
  68. char *argv[];
  69. void *p;
  70. {
  71.     struct sockaddr fsocket;
  72.     int i, k, s, r, t;
  73.     char *cp, limbo[] = "Limbo!";
  74.  
  75.     struct session *sp = (struct session *)p;
  76.  
  77.     if(argc > 1){
  78.         if((sp = sessptr(argv[1])) != NULLSESSION)
  79.             go(0,NULL,sp);
  80.         else
  81.             tputs(Badsess);
  82.         return 0;
  83.     }
  84.     tputs(" #  S#  Type     Rcv-Q Snd-Q State        Remote socket\n");
  85.     for(sp = Sessions; sp < &Sessions[Nsessions]; sp++){
  86.         if(sp->type == FREE || sp->type == COMMAND || sp->type == TRACESESSION)
  87.             continue;
  88.  
  89.         /* Rcv-Q includes output pending at the screen driver */
  90.         r = socklen(sp->output,1);
  91.         t = 0;
  92.         cp = NULLCHAR;
  93.         if((s = sp->s) != -1){
  94.             i = SOCKSIZE;
  95.             s = sp->s;
  96.             k = getpeername(s,(char *)&fsocket,&i);
  97.             r += socklen(s,0);
  98.             t += socklen(s,1);
  99.             cp = sockstate(s);
  100.         }
  101.  
  102.         tprintf("%s%-3u%-4d",
  103.             (Lastcurr == sp) ? "*" : " ",(unsigned)(sp - Sessions) - 1,s);
  104.         tprintf("%-8s%6d%6d %-13s%s",
  105.             Sestypes[sp->type],r,t,(cp != NULLCHAR) ? cp : limbo,
  106.             (sp->name != NULLCHAR) ? sp->name : "");
  107.         if(sp->s != -1 && k == 0)
  108.             tprintf(" (%s)",psocket(&fsocket));
  109.         tputs("\n");
  110.  
  111.         if(sp->type == FTP && (s = sp->cb.ftp->data) != -1){
  112.             /* Display data channel, if any */
  113.             i = SOCKSIZE;
  114.             k = getpeername(s,(char *)&fsocket,&i);
  115.             r = socklen(s,0);
  116.             t = socklen(s,1);
  117.             cp = sockstate(s);
  118.             tprintf("    %-4d%-8s%6d%6d %-13s%s",
  119.                 s,Sestypes[sp->type],r,t,(cp != NULLCHAR) ? cp : limbo,
  120.                 (sp->name != NULLCHAR) ? sp->name : "");
  121.             if(k == 0)
  122.                 tprintf(" (%s)",psocket(&fsocket));
  123.             tputs("\n");
  124.         }
  125.         if(sp->rfile != NULLCHAR)
  126.             tprintf("    Record: %s\n",sp->rfile);
  127.         if(sp->ufile != NULLCHAR)
  128.             tprintf("    Upload: %s\n",sp->ufile);
  129.     }
  130.     return 0;
  131. }
  132. /* Resume current session, and wait for it */
  133. int
  134. go(argc,argv,p)
  135. int argc;
  136. char *argv[];
  137. void *p;
  138. {
  139.     struct session *sp = (struct session *)p, *sptmp = Current;
  140.  
  141.     if(sp == NULLSESSION || sp->type == FREE
  142.       || (sptmp == Trace && sp->type == TRACESESSION)
  143.       || (sptmp == Command && sp->type == COMMAND))
  144.         return 0;
  145.     Current = sp;
  146.     swapscreen(sptmp,sp);
  147.     psignal(sp,0);
  148.     return 0;
  149. }
  150. int
  151. doclose(argc,argv,p)
  152. int argc;
  153. char *argv[];
  154. void *p;
  155. {
  156.     struct session *sp = (struct session *)p;
  157.  
  158.     if(argc > 1)
  159.         sp = sessptr(argv[1]);
  160.  
  161.     if(sp == NULLSESSION){
  162.         tputs(Badsess);
  163.         return -1;
  164.     }
  165.     shutdown(sp->s,1);
  166.     return 0;
  167. }
  168. int
  169. doreset(argc,argv,p)
  170. int argc;
  171. char *argv[];
  172. void *p;
  173. {
  174.     struct session *sp = (struct session *)p;
  175.  
  176.     if(argc > 1)
  177.         sp = sessptr(argv[1]);
  178.  
  179.     if(sp == NULLSESSION){
  180.         tputs(Badsess);
  181.         return -1;
  182.     }
  183.     /* Unwedge anyone waiting for a domain resolution, etc */
  184.     alert(sp->proc,(void *)EABORT);
  185.     shutdown(sp->s,2);
  186.     if(sp->type == FTP)
  187.         shutdown(sp->cb.ftp->data,2);
  188.     return 0;
  189. }
  190. int
  191. dokick(argc,argv,p)
  192. int argc;
  193. char *argv[];
  194. void *p;
  195. {
  196.     struct session *sp = (struct session *)p;
  197.  
  198.     if(argc > 1)
  199.         sp = sessptr(argv[1]);
  200.  
  201.     if(sp == NULLSESSION){
  202.         tputs(Badsess);
  203.         return -1;
  204.     }
  205.     sockkick(sp->s);
  206.     if(sp->type == FTP)
  207.         sockkick(sp->cb.ftp->data);
  208.     return 0;
  209. }
  210.  
  211. struct session *
  212. newsession(name,type,split,swap)
  213. char *name;
  214. int type, split, swap;
  215. {
  216.     struct session *sp;
  217.     int i;
  218.  
  219.     for(i = 0, sp = Sessions; i < Nsessions; sp++, i++)
  220.         if(sp->type == FREE)
  221.             break;
  222.     if(i == Nsessions)
  223.         return NULLSESSION;
  224.  
  225.     sp->type = type;
  226.     sp->s = -1;
  227.  
  228.     if(name != NULLCHAR)
  229.         sp->name = strxdup(name);
  230.  
  231.     sp->proc = Curproc;
  232.     /* Create standard input and output sockets. Output is
  233.      * translated to local end-of-line by default
  234.      */
  235.     Curproc->input =  sp->input = socket(AF_LOCAL,SOCK_STREAM,0);
  236.     seteol(Curproc->input,Eol);
  237.     sockmode(Curproc->input,SOCK_BINARY);
  238.     Curproc->output = sp->output = socket(AF_LOCAL,SOCK_STREAM,0);
  239.     seteol(Curproc->output,Eol);
  240.     sockmode(Curproc->output,SOCK_ASCII);
  241.  
  242.     /* on by default */
  243.     sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
  244.     sp->flowmode = Raw;            /* off by default */
  245.     sp->split = split;
  246.     sp->row = (split) ? Nrows - 5 : Nrows - 3;
  247.     sp->morewait = 0;
  248.     sp->swap = swap;
  249.     sp->cont = 0;
  250.     newscreen(sp);
  251.  
  252.     if(swap) {
  253.         swapscreen(Current,sp);
  254.         Current = sp;
  255.     }
  256.     return sp;
  257. }
  258. void
  259. freesession(sp)
  260. struct session *sp;
  261. {
  262.     int i;
  263.  
  264.     if(sp == NULLSESSION)
  265.         return;
  266.     usflush(sp->output);
  267.  
  268.     for(i = 0; i < 500; i++) ;
  269.  
  270.     if(sp->proc1 != NULLPROC) {
  271.         killproc(sp->proc1);
  272.         sp->proc1 = NULLPROC;
  273.     }
  274.     if(sp->proc2 != NULLPROC) {
  275.         killproc(sp->proc2);
  276.         sp->proc2 = NULLPROC;
  277.     }
  278.     free_p(sp->ttystate.line);
  279.     sp->ttystate.line = NULLBUF;
  280.     if(sp->s != -1)
  281.         close_s(sp->s);
  282.  
  283.     if(sp->record != NULLFILE) {
  284.         fclose(sp->record);
  285.         sp->record = NULLFILE;
  286.         xfree(sp->rfile);
  287.     }
  288.     if(sp->upload != NULLFILE) {
  289.         fclose(sp->upload);
  290.         sp->upload = NULLFILE;
  291.         xfree(sp->ufile);
  292.     }
  293.     if(sp->name != NULLCHAR)
  294.         xfree(sp->name);
  295.     sp->name = NULLCHAR;
  296.     sp->rfile = NULLCHAR;
  297.     sp->ufile = NULLCHAR;
  298.  
  299.     close_s(sp->input);
  300.     close_s(sp->output);
  301.     freescreen(sp);
  302.  
  303.     sp->type = FREE;
  304.  
  305.     if(Current == sp){
  306.         Current = (Lastcurr == Trace) ? Trace : Command;
  307.         swapscreen(NULLSESSION,Current);
  308.         alert(Display,(void *)1);
  309.     }
  310.  
  311.     if(Lastcurr == sp)
  312.         Lastcurr = NULLSESSION;
  313. }
  314. /* Control session recording */
  315. int
  316. dorecord(argc,argv,p)
  317. int argc;
  318. char *argv[];
  319. void *p;
  320. {
  321.     struct session *sp = (struct session *)p;
  322.  
  323.     if(argc > 2) {
  324.         sp = sessptr(argv[1]);
  325.         argc--;
  326.         argv++;
  327.     }
  328.     if(sp == NULLSESSION) {
  329.         tputs(Badsess);
  330.         return -1;
  331.     }
  332.     if(argc > 1){
  333.         if(sp->rfile != NULLCHAR){
  334.             fclose(sp->record);
  335.             xfree(sp->rfile);
  336.             sp->record = NULLFILE;
  337.             sp->rfile = NULLCHAR;
  338.         }
  339.         /* Open new record file, unless file name is "off", which means
  340.          * disable recording
  341.          */
  342.         if(strcmp(argv[1],"off") != 0){
  343.             if((sp->record = open_file(argv[1],
  344.               (sockmode(sp->output,-1) == SOCK_ASCII) ? APPEND_TEXT : APPEND_BINARY,
  345.               0,1)) == NULLFILE)
  346.                 return -1;
  347.             else
  348.                 sp->rfile = strxdup(argv[1]);
  349.         }
  350.     }
  351.     if(sp->rfile != NULLCHAR)
  352.         tprintf("Recording into %s\n",sp->rfile);
  353.     else
  354.         tputs("Recording off\n");
  355.  
  356.     return 0;
  357. }
  358. /* Control file transmission */
  359. int
  360. doupload(argc,argv,p)
  361. int argc;
  362. char *argv[];
  363. void *p;
  364. {
  365.     struct session *sp = (struct session *)p;
  366.  
  367.     if(argc > 2) {
  368.         sp = sessptr(argv[1]);
  369.         argc--;
  370.         argv++;
  371.     }
  372.     if(sp == NULLSESSION) {
  373.         tputs(Badsess);
  374.         return -1;
  375.     }
  376.     if(argc < 2){
  377.         tprintf("Uploading %s\n",(sp->ufile != NULLCHAR) ? sp->ufile : "off");
  378.         return 0;
  379.     }
  380.     if(strcmp(argv[1],"off") == 0 && sp->upload != NULLFILE){
  381.         /* Abort upload */
  382.         fclose(sp->upload);
  383.         sp->upload = NULLFILE;
  384.         xfree(sp->ufile);
  385.         sp->ufile = NULLCHAR;
  386.         killproc(sp->proc2);
  387.         sp->proc2 = NULLPROC;
  388.         return 0;
  389.     }
  390.     /* Open upload file */
  391.     if((sp->upload = open_file(argv[1],READ_TEXT,0,1)) == NULLFILE)
  392.         return -1;
  393.  
  394.     sp->ufile = strxdup(argv[1]);
  395.     /* All set, invoke the upload process */
  396.     sp->proc2 = newproc("upload",1024,upload,0,sp,NULL,0);
  397.     return 0;
  398. }
  399.  
  400. /* File uploading task */
  401. static void
  402. upload(unused,sp1,p)
  403. int unused;
  404. void *sp1;
  405. void *p;
  406. {
  407.     int c, oldf;
  408.  
  409.     struct session *sp = (struct session *)sp1;
  410.  
  411.     /* Disable newline buffering for the duration */
  412.     oldf = setflush(sp->s,-1);
  413.  
  414.     while((c = getc(sp->upload)) != EOF)
  415.         usputc(sp->s,(char)c);
  416.  
  417.     usflush(sp->s);
  418.     setflush(sp->s,oldf);
  419.  
  420.     fclose(sp->upload);
  421.     sp->upload = NULLFILE;
  422.     xfree(sp->ufile);
  423.     sp->ufile = NULLCHAR;
  424.     sp->proc2 = NULLPROC;
  425. }
  426.  
  427.  
  428.